package core.algorithms;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import core.interfaces.IBooleanOperator;
import core.interfaces.IState;

/**
 * implements basic HC algorithm for object of type T
 * @author Adam
 *
 * @param <T>
 */
public class BasicHillClimbing<T> extends HillClimbing<T>
{
	/**
	 * 
	 */
	private static final long serialVersionUID = -5684425727965212657L;


	public BasicHillClimbing(SearchParameters<T> searchParameters)
	{
		super(searchParameters);
		Date date = new Date();
		m_Randomizer.setSeed(date.getTime());
//		m_MaximumSteps = searchParameters.getMaximumHeuristicCalls();
		m_SearchParameters = searchParameters;
	}
	
	@Override
	protected SearchResults<T> doAlgorithm(IState<T> initialState)
	{
		IState<T> currentState = initialState;
		while (isDoAnotherIteration(m_SearchParameters.isBoundHeuristicCalls()))
		{
			// go over all the neighbors of the current node
			// look for the next best neighbor
			
			double currentVal = callHeuristicFunction(currentState);
			List<IBooleanOperator> bestOperators = new ArrayList<IBooleanOperator>();
			List<? extends IBooleanOperator> possibleOperators = currentState.getPossibleOperators();

			double bestVal = findBestOperator(currentState, currentVal, bestOperators, possibleOperators);
			
			// after iterating all the operators
			// we check the final iteration result
			if (bestVal <= currentVal)
			{
				break;
			}
			else
			{
				// continue to the next iteration
				currentState = getRandom(bestOperators, currentState);
			}
			super.stepFinished();
		}
//		m_FinalState = currentState;
//		m_FinalResult = m_Heuristic.getValue(currentState);
//		m_IsFinished = true;
		
		return new SearchResults<T>(
				currentState,
				super.callHeuristicFunction(currentState),
//				m_Heuristic.getValue(currentState),
				(m_StepsTaken == getSearchParameters().getMaximumHeuristicCalls()),
				m_StepsTaken);
//		)
//		
//		return currentState;
	}

	
	@Override
	public String getAlgorithmName()
	{
		return "BASIC HC";
	}
}


